package utils

import (
	"bytes"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
)

var HttpClient = new(httpClient)

type httpClient struct {
	client *http.Client
}

// Get 参数为url传参
func (c httpClient) Get(uri string, params, headers map[string]string) (bs []byte, err error) {
	c.client = &http.Client{}

	if len(params) > 0 {
		queryParams := url.Values{}
		for k, v := range params {
			queryParams.Add(k, v)
		}
		uri += "?" + queryParams.Encode()
	}
	req, err := http.NewRequest("GET", uri, nil)
	if err != nil {
		return
	}
	// 设置请求头
	for k, v := range headers {
		req.Header.Set(k, v)
	}
	// 发送请求
	resp, err := c.client.Do(req)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	// 检查响应状态码
	if resp.StatusCode == http.StatusNoContent {
		err = nil
		return
	}
	if resp.StatusCode == http.StatusOK {
		bs, err = io.ReadAll(resp.Body)
		return
	}
	bs, _ = io.ReadAll(resp.Body)
	err = fmt.Errorf("HttpClient Get status:[%d],err:[%s],status", resp.StatusCode, string(bs))
	return
}

// Post post请求，参数为 application/json
func (c httpClient) Post(uri string, jsonBody []byte, headers map[string]string) (bs []byte, err error) {
	c.client = &http.Client{}
	// 创建请求
	req, err := http.NewRequest("POST", uri, bytes.NewBuffer(jsonBody))
	if err != nil {
		return
	}
	// 设置请求头
	req.Header.Set("Content-Type", "application/json")
	for k, v := range headers {
		req.Header.Set(k, v)
	}
	// 发送请求
	resp, err := c.client.Do(req)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	// 检查响应状态码
	if resp.StatusCode == http.StatusNoContent {
		err = nil
		return
	}
	if resp.StatusCode == http.StatusOK {
		bs, err = io.ReadAll(resp.Body)
		return
	}
	bs, _ = io.ReadAll(resp.Body)
	err = fmt.Errorf("HttpClient Post() status:[%d],err:[%s],status", resp.StatusCode, string(bs))
	return
}

// Form 通过表单发送文件
func (c httpClient) Form(uri string, filePaths []string, headers map[string]string) (bs []byte, err error) {
	c.client = &http.Client{}
	// 准备请求体
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	// 添加文件部分
	for _, filePath := range filePaths {
		var file *os.File
		file, err = os.Open(filePath)
		if err != nil {
			return
		}
		defer file.Close()
		var part io.Writer
		part, err = writer.CreateFormFile(file.Name(), filepath.Base(filePath))
		if err != nil {
			return
		}
		_, err = io.Copy(part, file)
		if err != nil {
			return
		}
	}
	// 关闭writer以完成请求体
	err = writer.Close()
	if err != nil {
		return
	}
	// 创建请求
	req, err := http.NewRequest("POST", uri, body)
	if err != nil {
		return nil, err
	}
	// 设置请求头
	req.Header.Set("Content-Type", writer.FormDataContentType())
	for key, val := range headers {
		req.Header.Set(key, val)
	}

	// 发送请求
	resp, err := c.client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	// 检查响应状态码
	if resp.StatusCode == http.StatusNoContent {
		err = nil
		return
	}
	if resp.StatusCode == http.StatusOK {
		bs, err = io.ReadAll(resp.Body)
		return
	}
	bs, _ = io.ReadAll(resp.Body)
	err = fmt.Errorf("HttpClient Form() status:[%d],err:[%s],status", resp.StatusCode, string(bs))
	return
}
